package com.yungu.swift.admin.route.marketing;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.admin.utils.WorkbookUtil;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.model.PageVo;
import com.yungu.swift.base.model.admin.AdminStatusParam;
import com.yungu.swift.base.model.annotation.ResponseImgOverride;
import com.yungu.swift.constants.MagicConstant;
import com.yungu.swift.system.marketing.model.dto.MarketingGiftDto;
import com.yungu.swift.system.marketing.model.enums.MarketingErrorEnum;
import com.yungu.swift.system.marketing.model.param.AdminCouponDriInviteDriParam;
import com.yungu.swift.system.marketing.model.param.AdminCouponGiftHistoryPageParam;
import com.yungu.swift.system.marketing.model.param.AdminCouponGiftPageParam;
import com.yungu.swift.system.marketing.model.param.AdminCouponGiftParam;
import com.yungu.swift.system.marketing.model.vo.AdminMarketingGiftVo;
import com.yungu.swift.system.marketing.service.MarketingGiftCodeService;
import com.yungu.swift.system.marketing.service.MarketingGiftService;
import com.yungu.swift.utils.ParamUtil;
import com.yungu.swift.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.yungu.swift.admin.consts.AdminErrorEnum.FILE_TYPE_ERROR;
import static com.yungu.swift.admin.consts.AdminErrorEnum.PARAM_ERROR;
import static com.yungu.swift.system.marketing.model.dto.MarketingGiftDto.*;

/**
 * @author : cuixiuyin
 * @date : 2019/8/2
 */
@RestController
@RequestMapping("/admin/v1/marketing/coupon/gift")
@Api(value = "【营销管理】", tags = "优惠券礼包管理")
public class CouponGiftAdmin {

    @Reference
    private MarketingGiftService marketingGiftService;
    @Reference
    private MarketingGiftCodeService marketingGiftCodeService;

    @RequestMapping(value = "/queryPage", method = RequestMethod.POST)
    @ApiOperation(value = "优惠券礼包分页查询", httpMethod = "POST")
    public ResponseData<PageVo<MarketingGiftDto>> queryPage(@RequestBody AdminCouponGiftPageParam giftPageParam) {
        return marketingGiftService.queryPage(giftPageParam);
    }

    @ResponseImgOverride
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    @ApiOperation(value = "优惠券礼包详情", httpMethod = "GET")
    public ResponseData<AdminMarketingGiftVo> detail(@RequestParam String uuid) {
        return marketingGiftService.detail(uuid);
    }

    @RequestMapping(value = "/listCodeByGiftUuid", method = RequestMethod.GET)
    @ApiOperation(value = "优惠券礼包中的兑换码/口令信息", httpMethod = "GET")
    public ResponseData<List<String>> listCDKeyByGiftUuid(@RequestParam String uuid) {
        return marketingGiftCodeService.listCDKeyByGiftUuid(uuid);
    }

    @RequestMapping(value = "/history/queryPage", method = RequestMethod.POST)
    @ApiOperation(value = "优惠券礼包(历史发放记录)分页查询", httpMethod = "POST")
    public ResponseData<PageVo<MarketingGiftDto>> queryPageGift(@RequestBody AdminCouponGiftHistoryPageParam historyPageParam) {
        return marketingGiftService.historyGiftQueryPage(historyPageParam);
    }

    @RequestMapping(value = "/setStatus", method = RequestMethod.POST)
    @ApiOperation(value = "设置礼包状态", httpMethod = "POST")
    public ResponseData<Boolean> setStatusGift(@RequestBody AdminStatusParam statusParam) {
        if (ParamUtil.isIllegal(statusParam.getUuid(), statusParam.getStatus())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        return marketingGiftService.setStatus(statusParam.getUuid(), statusParam.getStatus());
    }

    @RequestMapping(value = "/saveOrUpdate", method = RequestMethod.POST)
    @ApiOperation(value = "新增或更新", httpMethod = "POST")
    public ResponseData<Boolean> saveOrUpdate(@RequestBody AdminCouponGiftParam couponGiftParam) {
        // 参数校验
        if (ParamUtil.isIllegal(couponGiftParam.getName(), couponGiftParam.getType(), couponGiftParam.getRemainNumber())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        // 乘客邀请/司机邀请
        if (GIFT_PASSENGER_INVITE == couponGiftParam.getType() || GIFT_DRIVER_INVITE == couponGiftParam.getType()) {
            if (ParamUtil.isIllegal(couponGiftParam.getGetMode(), couponGiftParam.getInvitedRewardMethod(),
                    couponGiftParam.getInvitedGiftName())) {
                return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
            }
        }
        // 乘客邀请
        if (GIFT_PASSENGER_INVITE == couponGiftParam.getType() && ParamUtil.isIllegal(couponGiftParam.getInviteRewardMethod())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        // 司机邀请
        if (GIFT_DRIVER_INVITE == couponGiftParam.getType() && ParamUtil.isIllegal(couponGiftParam.getDriverCashback())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        // 二维码微信链接
        if (GIFT_QR_CODE == couponGiftParam.getType() && ParamUtil.isIllegal(couponGiftParam.getLimitDrawType(),
                couponGiftParam.getEffectiveDate(), couponGiftParam.getExpiryDate())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        // 一次性发放
        if (GIFT_ONCE_SEND == couponGiftParam.getType() && ParamUtil.isIllegal(couponGiftParam.getSendType())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        // 兑换码/口令
        if (GIFT_REDEEM_CODE == couponGiftParam.getType()) {
            if (ParamUtil.isIllegal(couponGiftParam.getEffectiveDate(), couponGiftParam.getExpiryDate(),
                    couponGiftParam.getCodeType())) {
                return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
            }
            //如果为新增状态 库存量不能小于1
            if (StringUtils.isEmpty(couponGiftParam.getUuid()) && Optional.ofNullable(couponGiftParam.getRemainNumber()).orElse(0) < 1) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "库存量不能小于1");
            }
            // 校验口令是否重复
            if (couponGiftParam.getUuid()==null && couponGiftParam.getPasswordsCode() != null) {
                ResponseData<Boolean> verifyCode = marketingGiftCodeService.findCodeExists(couponGiftParam.getPasswordsCode());
                if (!verifyCode.isSuccess()) {
                    return verifyCode;
                }
            }
        }
        couponGiftParam.setAgentUuid(couponGiftParam.getUserAgentUuid());
        couponGiftParam.setCompanyUuid(couponGiftParam.getUserCompanyUuid());
        return marketingGiftService.saveOrUpdate(couponGiftParam, couponGiftParam.getHasChangeCoupon()
                == MagicConstant.INT_ONE);
    }

    @RequestMapping(value = "/driInviteDri", method = RequestMethod.POST)
    @ApiOperation(value = "司机邀请司机更新接口", httpMethod = "POST")
    public ResponseData<Boolean> driInviteDri(@RequestBody AdminCouponDriInviteDriParam driInviteDriParam) {
        MarketingGiftDto marketingGiftDto = new MarketingGiftDto();
        marketingGiftDto.setUuid(driInviteDriParam.getGiftUuid());
        marketingGiftDto.setDriverCashback(BigDecimal.valueOf(driInviteDriParam.getDriverCashback()));
        return marketingGiftService.edit(marketingGiftDto);
    }

    @RequestMapping(value = "/downloadCDKey", method = RequestMethod.GET)
    @ApiOperation(value = "下载兑换码口令（包括该礼包已经存在的兑换码口令）", httpMethod = "GET")
    public void downloadCDKey(@RequestParam String giftUuid, HttpServletResponse response) {
        try (OutputStream os = response.getOutputStream()) {
            List<String> cdKeyList = marketingGiftCodeService.listCDKeyByGiftUuid(giftUuid).getData();
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet();
            sheet.autoSizeColumn(0, true);
            //宽度50.38
            sheet.setColumnWidth(1, ((30 + 1) * 7 + 5) / 7 * 256);
            //创建第一行
            Row row = sheet.createRow(0);
            row.createCell(0).setCellValue("兑换码/口令");
            for (int rowNum = 0, len = cdKeyList.size(); rowNum < len; rowNum++) {
                Row dataRow = sheet.createRow(rowNum + 1);
                dataRow.createCell(0).setCellValue(cdKeyList.get(rowNum));
            }
            response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("CDKey.xlsx", "UTF-8"));
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            workbook.write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "/uploadCdkey", method = RequestMethod.POST)
    @ApiOperation(value = "上传兑换码口令，获取兑换码/口令列表", httpMethod = "POST")
    public ResponseData<List<String>> uploadPictures(@RequestPart("file") MultipartFile file) {
        String fileName = file.getOriginalFilename().toLowerCase();
        if (fileName.endsWith(MagicConstant.FILE_EXCEL_XLS) || fileName.endsWith(MagicConstant.FILE_EXCEL_XLSX)) {
            try (InputStream inputStream = file.getInputStream()) {
                //读取上传文件
                Workbook workBook = WorkbookFactory.create(inputStream);
                Sheet sheet = workBook.getSheetAt(0);
                if (sheet == null) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "找不到对应的 sheet");
                }
                List<String> redeemCodes = new ArrayList<>();
                // 略过第一行的列头
                for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
                    Row row = sheet.getRow(rowNum);
                    String redeemCode = WorkbookUtil.getCellValue(row.getCell(0));
                    // 校验重复
                    if (redeemCodes.contains(redeemCode)) {
                        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "表格中存在重复的兑换码");
                    }
                    // 校验格式 中文英文数字 最小6位最大20位
                    if (!redeemCode.matches("^[\\u4e00-\\u9fa5a-zA-Z0-9]{6,20}$")) {
                        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "格式错误，只允许输入中文英文数字,最小6位最大20位的兑换码。");
                    }
                    // 添加单元格数据
                    redeemCodes.add(redeemCode);
                }
                if (!redeemCodes.isEmpty()) {
                    List<String> repeatRedeemCodes = marketingGiftCodeService.findRepeatRedeemCodes(redeemCodes).getData();
                    if (!repeatRedeemCodes.isEmpty()) {
                        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, StringUtils.join(repeatRedeemCodes, ",") + "已存在");
                    }
                    return ResponseData.buildSuccessResponse(redeemCodes);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InvalidFormatException e) {
                e.printStackTrace();
            }
        }
        return ResponseData.buildErrorResponse(FILE_TYPE_ERROR.getCode(), FILE_TYPE_ERROR.getMsg());
    }
}
